package com.example.compose.jetsurvey.survey

import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel

private const val CONTENT_ANIMATION_DURATION = 300


@OptIn(ExperimentalAnimationApi::class)
@Composable
fun SurveyRoute(
    onSurveyComplete: () -> Unit,
    onNavUp: () -> Unit
) {
    val context = LocalContext.current
    val viewModel: SurveyViewModel = viewModel(
        factory = SurveyViewModelFactory(
            photoUriManager = PhotoUriManager(
                context
            )
        )
    )
    val surveyScreenData = viewModel.surveyScreenData

    BackHandler {
        if (!viewModel.onBackPressed()) {
            onNavUp()
        }
    }

    SurveyQuestionsScreen(
        surveyScreenData = surveyScreenData,
        isNextEnabled = viewModel.isNextEnabled,
        onClosePressed = { onNavUp() },
        onPreviousPressed = { viewModel.onPreviousPressed() },
        onNextPressed = { viewModel.onNextPressed() },
        onDonePressed = { viewModel.onDonePressed(onSurveyComplete) }
    ) { paddingValues ->

        val modifier = Modifier.padding(paddingValues = paddingValues)
        AnimatedContent(
            targetState = surveyScreenData,
            transitionSpec = {
                if (targetState.questionIndex > initialState.questionIndex) {
                    slideIntoContainer(
                        towards = AnimatedContentTransitionScope.SlideDirection.Left,
                        animationSpec = tween(durationMillis = 600)
                    ) togetherWith fadeOut(
                        animationSpec = tween(durationMillis = 600)
                    )
                } else {
                    fadeIn(
                        animationSpec = tween(durationMillis = 600)
                    ) togetherWith slideOutOfContainer(
                        towards = AnimatedContentTransitionScope.SlideDirection.Right,
                        animationSpec = tween(600)
                    )
                }.apply {
                    targetContentZIndex = targetState.questionIndex.toFloat()
                }
            },
            label = "surveyScreenDataAnimation"
        ) { targetState ->
            when (targetState.surveyQuestion) {
                SurveyQuestion.FREE_TIME -> {
                    FreeTimeQuestion(
                        onOptionSelected = viewModel::onFreeTimeResponse,
                        selectedAnswers = viewModel.freeTimeResponse,
                        modifier = modifier
                    )
                }

                SurveyQuestion.SUPERHERO -> {
                    SuperHeroQuestion(
                        onOptionSelected = viewModel::onSuperHeroResponse,
                        selectedAnswers = viewModel.superHeroResponse,
                        modifier = modifier
                    )
                }

                SurveyQuestion.LAST_TAKE_WAY -> {
                    val openDatePickerDialog = remember {
                        mutableStateOf(false)
                    }
                    TakeawayQuestion(
                        modifier = modifier.fillMaxSize(),
                        dateInMillis = viewModel.takeawayResponse,
                        onClick = {
                            openDatePickerDialog.value = true
                        }
                    )
                    PickerDate(
                        dateInMillis = viewModel.takeawayResponse,
                        openDatePickerDialog = openDatePickerDialog,
                        onClick = {
                            it?.let {
                                viewModel.onTakeawayResponse(it)
                            }
                        }
                    )
                }

                SurveyQuestion.FEELING_ABOUT_SELFIES -> FeelingAboutSelfiesQuestion(
                    value = viewModel.feelingAboutSelfiesResponse,
                    onValueChange = viewModel::onFeelingAboutSelfiesResponse,
                    modifier = modifier.fillMaxSize()
                )

                SurveyQuestion.TAKE_SELFIES -> TaskSelfieQuestion(
                    imageUri = viewModel.selfieUri,
                    getNewImageUri = viewModel::getNewSelfieUri,
                    onPhotoTaken = viewModel::onSelfieResponse,
                    modifier = modifier.fillMaxSize()
                )
            }
        }
    }
}


private fun getTransitionDirection(
    initialIndex: Int,
    targetIndex: Int
): AnimatedContentTransitionScope.SlideDirection {
    return if (targetIndex > initialIndex) {
        AnimatedContentTransitionScope.SlideDirection.Left
    } else {
        AnimatedContentTransitionScope.SlideDirection.Right
    }
}


